﻿using System;
using System.ServiceModel.Channels;
using System.Xml;

namespace SyncComm.Proxy
{
    /// <summary>
    /// Represents error thrown by WCF Sync Service during Synchronization
    /// </summary>
    public class CFFaultSyncException : System.ServiceModel.CommunicationException
    {

        //
        //Fields
        // 

        private Message _message;
        private string _faultMessage;
        private string _faultCode;
        private string _faultDetail;


        //
        // Constructors
        //

        /// <summary>
        /// Initializes a new instance of the <see cref="CFFaultSyncException"/> class.
        /// </summary>
        /// <param name="faultMessage">The fault message.</param>
        public CFFaultSyncException(string faultMessage)
        {
            this._faultMessage = faultMessage;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CFFaultSyncException"/> class.
        /// </summary>
        /// <param name="messageFault">The message fault.</param>
        public CFFaultSyncException(MessageBuffer messageFault)
        {
            //copy the original message
            _message = messageFault.CreateMessage();

            //create new XmlDocument 
            XmlDocument doc = new XmlDocument();
            //... and get the content
            doc.Load(_message.GetReaderAtBodyContents());

            //let's see the content depending on MessageVersion
            //Recall: Basic endpoint Soap11
            //Recall: Compressed endpoint Soap12WSAddressing10
            if (_message.Version == MessageVersion.Soap11)
            {
                XmlNode faultNode = doc.FirstChild;

                _faultCode = faultNode.ChildNodes[0].InnerText; //doc.ChildNodes[0].ChildNodes[0].InnerText;

                _faultMessage = faultNode.ChildNodes[1].InnerText; //doc.ChildNodes[0].ChildNodes[1].InnerText;

                if (faultNode.ChildNodes[2].HasChildNodes) //(doc.ChildNodes[0].ChildNodes[2].HasChildNodes)
                {
                    _faultDetail = faultNode.ChildNodes[2].FirstChild.InnerText; //doc.ChildNodes[0].ChildNodes[2].FirstChild.InnerText;
                }
            }
            else if (_message.Version == MessageVersion.Soap12WSAddressing10)
            {
                XmlNode faultNode = doc.ChildNodes[0];
                
                XmlNode codeNode = faultNode.FirstChild;
                _faultCode = codeNode.LastChild.FirstChild.InnerText; //faultNode.ChildNodes[0].ChildNodes[1].FirstChild.InnerText;

                XmlNode reasonNode = faultNode.ChildNodes[1];
                _faultMessage = reasonNode.FirstChild.InnerText;  //faultNode.ChildNodes[1].FirstChild.InnerText;

                XmlNode detailNode = faultNode.LastChild;
                _faultDetail = detailNode.FirstChild.InnerText; //faultNode.ChildNodes[2].FirstChild.InnerText;

            }

        }

        //
        // Properties (ReadOnly)
        //

        /// <summary>
        /// Gets the fault message.
        /// </summary>
        /// <value>The fault message.</value>
        public string FaultMessage
        {
            get { return _faultMessage; }
        }

        /// <summary>
        /// Gets the fault code.
        /// </summary>
        /// <value>The fault code.</value>
        public string FaultCode
        {
            get { return _faultCode; }
        }

        /// <summary>
        /// Gets the fault detail.
        /// </summary>
        /// <value>The fault detail.</value>
        public string FaultDetail
        {
            get { return _faultDetail; }
        }

        public bool HasDetail
        {
            get { return _faultDetail.Length > 0; }
        }
    }
}
